#include "epollModule.h"

#define EPOLL_IO_SIZE  1024 
#define EPOLL_MAX_EVENTS  4096

/*
 *
 */
int epollIoInit(struct ioCtx **io){
	struct ioCtx *tmp = *io;
	tmp->epollfd = epoll_create(EPOLL_IO_SIZE);
	if (tmp->epollfd == RET_ERROR){
		fprintf(stderr, "[error]%s in file:[%s] func:[%s] line:[%d]\n", strerror(errno), __FILE__, __func__, __LINE__);
		return RET_ERROR;
	}
	tmp->eventset = (struct epoll_event *)malloc(sizeof(struct epoll_event) * EPOLL_MAX_EVENTS);
	if (!tmp->eventset){
		fprintf(stderr, "[error]:%s in file:[%s] func:[%s] line:[%d]\n", strerror(errno), __FILE__, __func__,__LINE__);
		return RET_ERROR;
	}
	memset(tmp->eventset, 0, sizeof(struct epoll_event)*EPOLL_MAX_EVENTS);
	*io = tmp;
	return RET_OK;
}

/*
 *
 */
int epollModEvent(struct ioCtx *io, int fd, int op, int events){
	int iRet = RET_ERROR;
	if(fd < 0){
		fprintf(stderr, "[error]%s in file:[%s] func:[%s] line:[%d]\n", strerror(errno), __FILE__, __func__, __LINE__);
		return RET_ERROR;
	}
	struct epoll_event  ev;
    memset(&ev, 0, sizeof(struct epoll_event));
    ev.data.fd = fd;
	ev.events = events;
	iRet = epoll_ctl(io->epollfd, op, fd, &ev);	
	if(iRet == RET_ERROR){
		fprintf(stderr, "[error]%s in file:[%s] func:[%s] line:[%d]\n", strerror(errno), __FILE__, __func__, __LINE__);
		return RET_ERROR;
	}
	return RET_OK;
}


int epollDelEvent(struct ioCtx *io, int fd){
	int iRet = RET_ERROR;
	if(fd < 0){
		fprintf(stderr, "[error]get unavaliable fd:%d in file:[%s] func:[%s] line:[%d]\n", fd , __FILE__, __func__, __LINE__);
		return RET_ERROR;
	}
	struct epoll_event  ev;
	ev.data.fd = fd; 
	iRet = epoll_ctl(io->epollfd, EPOLL_CTL_DEL, fd, &ev);
	if(iRet == RET_ERROR){
		fprintf(stderr, "[error]%s in file:[%s] func:[%s] line:[%d]\n", strerror(errno), __FILE__, __func__, __LINE__);
		return RET_ERROR;
	}
	return RET_OK;
}

int epollWaitEvent(struct ioCtx *io, int timeout){
	int evCount = -1;
	if(io->epollfd == -1 || !io->eventset){
		fprintf(stderr, "[error]get unavaliable args!!\n");
		return RET_ERROR;
	}
	evCount = epoll_wait(io->epollfd, io->eventset, EPOLL_MAX_EVENTS, timeout);
	if(evCount <  0){
        if(errno == EINTR){
            return RET_OK; //被中断影响 
        }
	}else if(evCount == 0){
        return RET_OK;
	}
	return  evCount;
}

void epollIoDeinit(struct ioCtx *io){
	if(io->epollfd > 0){
		close(io->epollfd);
	}
	if(io->eventset){
		free(io->eventset);
		io->eventset = NULL;
	}
	if(io){
		free(io);
		io = NULL;
	}
}
